From: Nipunn Koorapati Date: Tue, 5 Sep 2017 16:40:01 +0000 (-0700) Subject: DP Cache target_metadata. Update all the lifetimes X-Git-Tag: archive/raspbian/0.35.0-2+rpi1~3^2^2^2^2^2^2^2~22^2~6^2~58^2~1 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/success//%22http:/www.example.com/cgi/success/?a=commitdiff_plain;h=67b3b44447f9b4390ab43c109a66d933c51f6430;p=cargo.git DP Cache target_metadata. Update all the lifetimes --- diff --git a/src/cargo/ops/cargo_rustc/context.rs b/src/cargo/ops/cargo_rustc/context.rs index afd36b826..ce3bba0a8 100755 --- a/src/cargo/ops/cargo_rustc/context.rs +++ b/src/cargo/ops/cargo_rustc/context.rs @@ -55,7 +55,9 @@ pub struct Context<'a, 'cfg: 'a> { host_info: TargetInfo, profiles: &'a Profiles, incremental_enabled: bool, + target_filenames: HashMap, Arc, bool)>>>, + target_metadatas: HashMap, Option>, } #[derive(Clone, Default)] @@ -154,7 +156,10 @@ impl<'a, 'cfg> Context<'a, 'cfg> { used_in_plugin: HashSet::new(), incremental_enabled: incremental_enabled, jobserver: jobserver, + + // TODO: Pre-Calculate these with a topo-sort, rather than lazy-calculating target_filenames: HashMap::new(), + target_metadatas: HashMap::new(), }) } @@ -362,13 +367,13 @@ impl<'a, 'cfg> Context<'a, 'cfg> { /// Returns the directory for the specified unit where fingerprint /// information is stored. - pub fn fingerprint_dir(&mut self, unit: &Unit) -> PathBuf { + pub fn fingerprint_dir(&mut self, unit: &Unit<'a>) -> PathBuf { let dir = self.pkg_dir(unit); self.layout(unit.kind).fingerprint().join(dir) } /// Returns the appropriate directory layout for either a plugin or not. - pub fn build_script_dir(&mut self, unit: &Unit) -> PathBuf { + pub fn build_script_dir(&mut self, unit: &Unit<'a>) -> PathBuf { assert!(unit.target.is_custom_build()); assert!(!unit.profile.run_custom_build); let dir = self.pkg_dir(unit); @@ -376,7 +381,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> { } /// Returns the appropriate directory layout for either a plugin or not. - pub fn build_script_out_dir(&mut self, unit: &Unit) -> PathBuf { + pub fn build_script_out_dir(&mut self, unit: &Unit<'a>) -> PathBuf { assert!(unit.target.is_custom_build()); assert!(unit.profile.run_custom_build); let dir = self.pkg_dir(unit); @@ -394,7 +399,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> { /// Returns the appropriate output directory for the specified package and /// target. - pub fn out_dir(&mut self, unit: &Unit) -> PathBuf { + pub fn out_dir(&mut self, unit: &Unit<'a>) -> PathBuf { if unit.profile.doc { self.layout(unit.kind).root().parent().unwrap().join("doc") } else if unit.target.is_custom_build() { @@ -406,7 +411,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> { } } - fn pkg_dir(&mut self, unit: &Unit) -> String { + fn pkg_dir(&mut self, unit: &Unit<'a>) -> String { let name = unit.pkg.package_id().name(); match self.target_metadata(unit) { Some(meta) => format!("{}-{}", name, meta), @@ -440,7 +445,17 @@ impl<'a, 'cfg> Context<'a, 'cfg> { /// We build to the path: "{filename}-{target_metadata}" /// We use a linking step to link/copy to a predictable filename /// like `target/debug/libfoo.{a,so,rlib}` and such. - pub fn target_metadata(&mut self, unit: &Unit) -> Option { + pub fn target_metadata(&mut self, unit: &Unit<'a>) -> Option { + if let Some(cache) = self.target_metadatas.get(unit) { + return cache.clone() + } + + let metadata = self.calc_target_metadata(unit); + self.target_metadatas.insert(*unit, metadata.clone()); + metadata + } + + fn calc_target_metadata(&mut self, unit: &Unit<'a>) -> Option { // No metadata for dylibs because of a couple issues // - OSX encodes the dylib name in the executable // - Windows rustc multiple files of which we can't easily link all of them @@ -521,7 +536,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> { } /// Returns the file stem for a given target/profile combo (with metadata) - pub fn file_stem(&mut self, unit: &Unit) -> String { + pub fn file_stem(&mut self, unit: &Unit<'a>) -> String { match self.target_metadata(unit) { Some(ref metadata) => format!("{}-{}", unit.target.crate_name(), metadata), @@ -546,7 +561,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> { /// Returns an Option because in some cases we don't want to link /// (eg a dependent lib) - pub fn link_stem(&mut self, unit: &Unit) -> Option<(PathBuf, String)> { + pub fn link_stem(&mut self, unit: &Unit<'a>) -> Option<(PathBuf, String)> { let src_dir = self.out_dir(unit); let bin_stem = self.bin_stem(unit); let file_stem = self.file_stem(unit); @@ -587,6 +602,15 @@ impl<'a, 'cfg> Context<'a, 'cfg> { return Ok(cache.clone()) } + let result = self.calc_target_filenames(unit); + if let Ok(ref ret) = result { + self.target_filenames.insert(*unit, ret.clone()); + } + result + } + + fn calc_target_filenames(&mut self, unit: &Unit<'a>) + -> CargoResult, bool)>>> { let out_dir = self.out_dir(unit); let stem = self.file_stem(unit); let link_stem = self.link_stem(unit); @@ -668,9 +692,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> { } info!("Target filenames: {:?}", ret); - let ret = Arc::new(ret); - self.target_filenames.insert(*unit, ret.clone()); - Ok(ret) + Ok(Arc::new(ret)) } fn used_deps(&self, unit: &Unit<'a>) -> CargoResult>> { diff --git a/src/cargo/ops/cargo_rustc/fingerprint.rs b/src/cargo/ops/cargo_rustc/fingerprint.rs index fd32f2b9c..38cef8f1c 100644 --- a/src/cargo/ops/cargo_rustc/fingerprint.rs +++ b/src/cargo/ops/cargo_rustc/fingerprint.rs @@ -538,7 +538,7 @@ fn write_fingerprint(loc: &Path, fingerprint: &Fingerprint) -> CargoResult<()> { } /// Prepare for work when a package starts to build -pub fn prepare_init(cx: &mut Context, unit: &Unit) -> CargoResult<()> { +pub fn prepare_init<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, unit: &Unit<'a>) -> CargoResult<()> { let new1 = cx.fingerprint_dir(unit); if fs::metadata(&new1).is_err() { @@ -548,7 +548,7 @@ pub fn prepare_init(cx: &mut Context, unit: &Unit) -> CargoResult<()> { Ok(()) } -pub fn dep_info_loc(cx: &mut Context, unit: &Unit) -> PathBuf { +pub fn dep_info_loc<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, unit: &Unit<'a>) -> PathBuf { cx.fingerprint_dir(unit).join(&format!("dep-{}", filename(cx, unit))) } @@ -670,7 +670,7 @@ fn mtime_if_fresh(output: &Path, paths: I) -> Option } } -fn filename(cx: &mut Context, unit: &Unit) -> String { +fn filename<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, unit: &Unit<'a>) -> String { // file_stem includes metadata hash. Thus we have a different // fingerprint for every metadata hash version. This works because // even if the package is fresh, we'll still link the fresh target diff --git a/src/cargo/ops/cargo_rustc/mod.rs b/src/cargo/ops/cargo_rustc/mod.rs index febeb1c54..02fa67727 100644 --- a/src/cargo/ops/cargo_rustc/mod.rs +++ b/src/cargo/ops/cargo_rustc/mod.rs @@ -684,10 +684,10 @@ fn root_path(cx: &Context, unit: &Unit) -> PathBuf { } } -fn build_base_args(cx: &mut Context, - cmd: &mut ProcessBuilder, - unit: &Unit, - crate_types: &[&str]) { +fn build_base_args<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, + cmd: &mut ProcessBuilder, + unit: &Unit<'a>, + crate_types: &[&str]) { let Profile { ref opt_level, lto, codegen_units, ref rustc_args, debuginfo, debug_assertions, overflow_checks, rpath, test, doc: _doc,